#
# Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
#
#   GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
#   Author :  Shawn.Tan
#   Date : 2025.10.28
#
#   History : Initial Version 2025.10.28
#
#
from base.exception_handlers.ExceptionHandlerAssignment import (
    ExceptionHandlerAssignment,
)


# This class represents the set of exception handlers assigned to execute in
# a given security state within a certain privilegel level for a certain
# thread.
class SecurityStateHandlerSet(object):
    def __init__(
        self,
        aSecurityState,
        aMemBankHandlerRegistryRepo,
        aFactory,
        aExceptionsStack,
    ):
        self._mSecurityState = aSecurityState
        self._mMemBankHandlerRegistryRepo = aMemBankHandlerRegistryRepo
        self._mFactory = aFactory
        self._mExceptionsStack = aExceptionsStack
        self._mHandlerAssignments = {}

    # Assign the specified handler within the specified memory bank to handle
    # the specified exception class or subexception class. If a handler is
    # already assigned to the exception class or subexception class, this
    # method does nothing. This allows user-specified exception handlers to be
    # specified first and default handlers to be inserted later only where
    # there are unhandled exception classes.
    #
    #  @param aAssignmentRequest An object containing information specifying
    #       an excpetion handler class and when it should be executed.
    def assignSynchronousExceptionHandler(self, aAssignmentRequest):
        mem_bank = aAssignmentRequest.mMemBank
        if mem_bank is None:
            mem_bank = self._mSecurityState.getDefaultMemoryBank()

        repo = self._mMemBankHandlerRegistryRepo
        mem_bank_handler_registry = repo.getMemoryBankHandlerRegistry(mem_bank)
        mem_bank_handler_registry.registerExceptHandlerWithClassName(
            aAssignmentRequest.mHandlerModuleName,
            aAssignmentRequest.mHandlerClassName,
            self._mFactory,
            self._mExceptionsStack,
        )

        if aAssignmentRequest.mSubexcClass is not None:
            self._assignSynchronousSubexceptionHandler(aAssignmentRequest, mem_bank)
        else:
            if aAssignmentRequest.mExcClass not in self._mHandlerAssignments:
                self._mHandlerAssignments[
                    aAssignmentRequest.mExcClass
                ] = ExceptionHandlerAssignment(mem_bank, aAssignmentRequest.mHandlerClassName)

    # Return all exception handler assignments.
    def getSynchronousExceptionHandlerAssignments(self):
        return self._mHandlerAssignments

    # Return the exception handler assignment for the specified exception class
    #
    #  @param aExceptionClass The type of exception.
    def getSynchronousExceptionHandlerAssignment(self, aExceptionClass):
        return self._mHandlerAssignments[aExceptionClass]

    # Assign the specified handler within the specified memory bank to handle
    # the specified subexception class. If a handler is already assigned to the
    # exception class or subexception class, this method does nothing.
    #
    #  @param aAssignmentRequest An object containing information specifying
    #       an excpetion handler class and when it should be executed.
    #  @param aMemBank The memory bank in which the handler should be
    #       generated.
    def _assignSynchronousSubexceptionHandler(self, aAssignmentRequest, aMemBank):
        handler_assignment = self._mHandlerAssignments.get(
            aAssignmentRequest.mExcClass,
            ExceptionHandlerAssignment(aMemBank),
        )

        # Only permit adding subassignments if the top-level exception
        # class does not have a handler assigned to handle it.
        if handler_assignment.mHandlerClassName is None:
            handler_assignment.addSubassignment(
                aAssignmentRequest.mSubexcClass,
                aAssignmentRequest.mHandlerClassName,
                aMemBank,
            )

        self._mHandlerAssignments[aAssignmentRequest.mExcClass] = handler_assignment
